package com.rency.ues.webapp.controller;

import com.rency.ues.webapp.common.BaseAction;
import com.rency.ues.webapp.common.WebProperty;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.rency.common.utils.domain.RespBody;
import org.rency.common.utils.security.MD5Utils;
import org.rency.ues.common.UesDict;
import org.rency.ues.common.model.EncryptData;
import org.rency.ues.common.model.EncryptItem;
import org.rency.ues.common.model.TransferBody;
import org.rency.ues.common.model.UesCredentials;
import org.rency.ues.domain.request.DecryptBatchRequest;
import org.rency.ues.domain.request.DecryptRequest;
import org.rency.ues.domain.request.EncryptBatchRequest;
import org.rency.ues.domain.request.EncryptRequest;
import org.rency.ues.domain.response.DecryptBatchResponse;
import org.rency.ues.domain.response.DecryptResponse;
import org.rency.ues.domain.response.EncryptBatchResponse;
import org.rency.ues.domain.response.EncryptResponse;
import org.rency.ues.domain.support.Certification;
import org.rency.ues.engine.manager.CertificationManager;
import org.rency.ues.engine.service.UesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * Restful资源服务
 *
 * @author: Created by user_rcy@163.com on 2016/8/8.
 * @version: V1.0.0
 * @since JDK 1.8
 */
@RestController
@RequestMapping("/rest")
public class RemoteController extends BaseAction{

    private static final Logger logger = LoggerFactory.getLogger(RemoteController.class);

    @Resource(name="webProperty")
    private WebProperty webProperty;

    @Resource(name="certificationManager")
    private CertificationManager certificationManager;

    @Resource(name="uesService")
    private UesService uesService;

    @RequestMapping(value="getCert.json",method= RequestMethod.POST)
    public @ResponseBody RespBody getCertInfo(@RequestBody TransferBody request){
        logger.info("获取证书信息,序列号:{}.",request);
        RespBody result = this.authValid(request.getCredentials());
        if(!result.isSuccess()){
            return result;
        }
        if(StringUtils.isBlank(request.getSerialNo())){
            request.setSerialNo(certificationManager.getLastedSerialNo());
        }
        Certification certification = certificationManager.getCertification(request.getSerialNo());
        if(certification == null){
            this.failed("证书不存在:"+request.getSerialNo());
            return respBody;
        }
        respData.put(UesDict.REST_PARAMETER_KEY_CERTIFICATION,certification.getCertBase());
        this.success(UesDict.CHINESE_SUCCESS_MSG);
        return respBody;
    }

    @RequestMapping(value="encrypt.json",method= RequestMethod.POST)
    public @ResponseBody RespBody encrypt(@RequestBody TransferBody request){
        logger.info("远程加密请求,{}.",request);
        RespBody result = this.authValid(request.getCredentials());
        if(!result.isSuccess()){
            return result;
        }
        if(request.getEnItems().size() == 1){
            EncryptRequest enRequest = new EncryptRequest();
            enRequest.setSerialNo(request.getSerialNo());
            EncryptItem enItem = request.getEnItems().get(0);
            if(enItem == null){
                this.failed("加密数据密文不能为空.");
                return this.respBody;
            }
            enRequest.setEncryptedData(enItem.getEncryptedData());
            enRequest.setEncryptedKey(enItem.getEncryptedKey());
            enRequest.setEncryptType(request.getEncryptType());
            EncryptResponse response = uesService.encrypt(enRequest);
            if(response == null || !response.isSuccess()){
                this.failed(response == null ? UesDict.CHINESE_FAIL_MSG : response.getReturnMessage());
                return this.respBody;
            }
            this.respData.put(response.getEncryptKey(),response.getTicket());
            this.success(UesDict.CHINESE_SUCCESS_MSG);
        }else if(request.getEnItems().size() > 1){
            EncryptBatchRequest batchRequest = new EncryptBatchRequest();
            batchRequest.setSerialNo(request.getSerialNo());
            batchRequest.setEncryptType(request.getEncryptType());
            batchRequest.setEncryptItems(request.getEnItems());
            EncryptBatchResponse batchResponse = uesService.encryptBatch(batchRequest);
            if(batchResponse == null || !batchResponse.isSuccess()){
                this.failed(batchResponse == null ? UesDict.CHINESE_FAIL_MSG : batchResponse.getReturnMessage());
                return this.respBody;
            }
            for(EncryptResponse response : batchResponse.getResponses()){
                this.respData.put(response.getEncryptKey(),response.getTicket());
            }
            this.success(UesDict.CHINESE_SUCCESS_MSG);
        }else{
            this.failed("加密数据项不能为空.");
        }
        return respBody;
    }

    @RequestMapping(value="decrypt.json",method= RequestMethod.POST)
    public @ResponseBody RespBody decrypt(@RequestBody TransferBody request){
        logger.info("远程解密请求,{}.",request);
        RespBody result = this.authValid(request.getCredentials());
        if(!result.isSuccess()){
            return result;
        }
        if(CollectionUtils.isEmpty(request.getTickets())){
            this.failed("解密数据项不能为空");
            return this.respBody;
        }
        if(request.getTickets().size() == 1){
            DecryptRequest deRequest = new DecryptRequest();
            deRequest.setTicket(request.getTickets().get(0));
            DecryptResponse response = uesService.decrypt(deRequest);
            if(response == null || !response.isSuccess()){
                this.failed(response == null ? UesDict.CHINESE_FAIL_MSG : response.getReturnMessage());
                return this.respBody;
            }
            this.fillRespData(response);
            this.success(UesDict.CHINESE_SUCCESS_MSG);
        }else if(request.getTickets().size() > 1){
            DecryptBatchRequest batchRequest = new DecryptBatchRequest();
            for(String ticket : request.getTickets()){
                batchRequest.addTicket(ticket);
            }
            DecryptBatchResponse batchResponse = uesService.decryptBatch(batchRequest);
            for(DecryptResponse response : batchResponse.getResponses()){
                this.fillRespData(response);
            }
            this.success(UesDict.CHINESE_SUCCESS_MSG);
        }else{
            this.failed("解密数据项不能为空");
        }
        return respBody;
    }

    /**
     * 身份校验
     * @param credentials
     * @return
     */
    private RespBody authValid(UesCredentials credentials){
        RespBody resp = new RespBody();
        logger.info("远程请求身份校验,{}.",credentials.getUserName());
        if(StringUtils.isBlank(credentials.getUserName()) || StringUtils.isBlank(credentials.getPassword())){
            resp.setMessage("身份校验信息不能为空.");
            resp.setSuccess(false);
            return resp;
        }
        UesCredentials targetCredentials = new UesCredentials();
        targetCredentials.setUserName(MD5Utils.MD5(webProperty.getUserName()));
        targetCredentials.setPassword(MD5Utils.MD5(webProperty.getPassword()));
        if(targetCredentials.isValid(credentials)){
            resp.setMessage("身份校验通过.");
            resp.setSuccess(true);
            return resp;
        }else {
            resp.setMessage("身份校验未通过.");
            resp.setSuccess(false);
            return resp;
        }
    }

    private void fillRespData(DecryptResponse response){
        EncryptData enData = new EncryptData();
        enData.setSerialNo(response.getSerialNo());
        enData.setEncryptType(response.getEncryptType());
        enData.setEncryptedKey(response.getEncryptedKey());
        enData.setEncryptedData(response.getEncryptedData());
        this.respData.put(response.getTicket(),enData);
        this.respData.put(UesDict.REST_PARAMETER_KEY_PRIVATE,response.getPrivateKey());
    }

}
